package com.measure

import android.content.Context
import android.content.pm.PackageManager
import android.util.Log
import com.google.ar.core.ArCoreApk
import com.google.ar.core.Session
import com.google.ar.core.TrackingState
import com.google.ar.core.Config
import com.google.ar.core.exceptions.*
import com.mrousavy.camera.frameprocessors.Frame
import com.mrousavy.camera.frameprocessors.FrameProcessorPlugin
import java.util.concurrent.atomic.AtomicBoolean

// AR引擎类型枚举
enum class AREngineType {
    GOOGLE_AR_CORE,
    HUAWEI_AR_ENGINE,
    UNSUPPORTED
}

class ARCorePlugin(
    private val context: Context,
    private val session: Any?,
    private val engineType: AREngineType,
    private val errorMessage: String?
) : FrameProcessorPlugin() {

    companion object {
        private const val TAG = "ARCorePlugin"
        private val isSessionRunning = AtomicBoolean(false)
        
        private const val HUAWEI_AR_ENGINE_PACKAGE = "com.huawei.arengine.service"
        
        fun create(context: Context, options: Map<String, Any>?): FrameProcessorPlugin {
            Log.d(TAG, "Initializing AR compatibility layer...")
            
            val (engineType, session, errorMessage) = initializeARSession(context)
            Log.d(TAG, "AR session initialized with engine: $engineType")
            
            return ARCorePlugin(context, session, engineType, errorMessage)
        }
        
        private fun initializeARSession(context: Context): Triple<AREngineType, Any?, String?> {
            // 核心逻辑：如果是华为/荣耀设备，强制使用华为AR Engine
            if (isHuaweiDevice()) {
                Log.d(TAG, "Huawei device detected - forcing Huawei AR Engine")
                return when {
                    isHuaweiAREngineAvailable(context) -> {
                        Log.d(TAG, "Huawei AR Engine is available")
                        val (session, error) = createHuaweiARSession(context)
                        Triple(AREngineType.HUAWEI_AR_ENGINE, session, error)
                    }
                    else -> {
                        Log.w(TAG, "Huawei AR Engine not available")
                        Triple(AREngineType.UNSUPPORTED, null, 
                            "Huawei device detected but AR Engine is not available. " +
                            "Please install Huawei AR Engine from AppGallery.")
                    }
                }
            }
            
            // 非华为设备：使用Google ARCore
            Log.d(TAG, "Non-Huawei device - using Google ARCore")
            return when {
                isGoogleARCoreSupported(context) -> {
                    Log.d(TAG, "Google ARCore is supported")
                    val (session, error) = createGoogleARCoreSession(context)
                    Triple(AREngineType.GOOGLE_AR_CORE, session, error)
                }
                else -> {
                    Log.w(TAG, "Google ARCore not supported")
                    Triple(AREngineType.UNSUPPORTED, null, 
                        "Device does not support Google ARCore")
                }
            }
        }
        
        private fun isHuaweiDevice(): Boolean {
            return try {
                val manufacturer = android.os.Build.MANUFACTURER.lowercase()
                val brand = android.os.Build.BRAND.lowercase()
                // 华为和荣耀设备判断
                manufacturer.contains("huawei") ||
                brand.contains("huawei")
            } catch (e: Exception) {
                false
            }
        }
        
        private fun isHuaweiAREngineAvailable(context: Context): Boolean {
            return try {
                val pm = context.packageManager
                pm.getPackageInfo(HUAWEI_AR_ENGINE_PACKAGE, PackageManager.GET_ACTIVITIES)
                Log.d(TAG, "Huawei AR Engine is installed")
                true
            } catch (e: PackageManager.NameNotFoundException) {
                Log.w(TAG, "Huawei AR Engine package not found")
                false
            } catch (e: Exception) {
                Log.w(TAG, "Error checking Huawei AR Engine: ${e.message}")
                false
            }
        }
        
        private fun isGoogleARCoreSupported(context: Context): Boolean {
            return try {
                // 只在非华为设备上检查Google ARCore
                if (isHuaweiDevice()) {
                    Log.d(TAG, "Huawei device - skipping Google ARCore check")
                    return false
                }
                
                val availability = ArCoreApk.getInstance().checkAvailability(context)
                Log.d(TAG, "Google ARCore availability: $availability")
                availability.isSupported
            } catch (e: Exception) {
                Log.w(TAG, "Error checking Google ARCore: ${e.message}")
                false
            }
        }
        
        private fun createGoogleARCoreSession(context: Context): Pair<Session?, String?> {
            return try {
                Log.d(TAG, "Creating Google ARCore session...")
                
                val availability = ArCoreApk.getInstance().checkAvailability(context)
                
                when {
                    availability.isSupported -> {
                        try {
                            val session = Session(context).apply {
                                val config = Config(this).apply {
                                    planeFindingMode = Config.PlaneFindingMode.HORIZONTAL
                                    focusMode = Config.FocusMode.AUTO
                                }
                                configure(config)
                            }
                            Log.d(TAG, "Google ARCore session created successfully")
                            Pair(session, null)
                        } catch (e: Exception) {
                            Log.e(TAG, "Failed to create ARCore session: ${e.message}", e)
                            Pair(null, "ARCore session creation failed: ${e.message}")
                        }
                    }
                    else -> {
                        val error = "Google ARCore not available: $availability"
                        Log.w(TAG, error)
                        Pair(null, error)
                    }
                }
            } catch (e: Exception) {
                val error = "Failed to create Google ARCore session: ${e.message}"
                Log.e(TAG, error, e)
                Pair(null, error)
            }
        }
        
        private fun createHuaweiARSession(context: Context): Pair<Any?, String?> {
            Log.d(TAG, "Creating Huawei AR Engine session...")
            
            // 临时方案：返回一个标记对象
            // 实际使用时需要集成华为AR Engine SDK
            val huaweiSession = "HUAWEI_AR_SESSION_PLACEHOLDER"
            
            return Pair(huaweiSession, "Huawei AR Engine integration required. " +
                "Please add Huawei AR Engine SDK dependency and implement Huawei AR logic.")
        }
    }

    override fun callback(frame: Frame, arguments: Map<String, Any>?): Any? {
        val result = mutableMapOf<String, Any?>()
        
        result["engineType"] = engineType.name
        result["isHuaweiDevice"] = isHuaweiDevice()
        
        // 检查是否有错误信息
        if (errorMessage != null) {
            result["error"] = errorMessage
            result["supported"] = false
            return result
        }

        if (session == null) {
            result["error"] = "AR session not available"
            result["supported"] = false
            return result
        }

        return when (engineType) {
            AREngineType.GOOGLE_AR_CORE -> processGoogleARCoreFrame(frame, arguments, result)
            AREngineType.HUAWEI_AR_ENGINE -> processHuaweiARFrame(frame, arguments, result)
            AREngineType.UNSUPPORTED -> {
                result["error"] = "Unsupported AR engine"
                result["supported"] = false
                result
            }
        }
    }
    
    private fun processGoogleARCoreFrame(frame: Frame, arguments: Map<String, Any>?, result: MutableMap<String, Any?>): Map<String, Any?> {
        val googleSession = session as? Session ?: run {
            result["error"] = "Google ARCore session not available"
            result["supported"] = false
            return result
        }

        val textureId = arguments?.get("textureId") as? Int ?: run {
            result["error"] = "Missing textureId argument"
            result["supported"] = false
            return result
        }

        return try {
            googleSession.setCameraTextureName(textureId)
            
            if (!isSessionRunning.get()) {
                googleSession.resume()
                isSessionRunning.set(true)
                Log.d(TAG, "Google ARCore session started")
            }
            
            val arFrame = googleSession.update()
            val camera = arFrame.camera
            
            when (camera.trackingState) {
                TrackingState.TRACKING -> {
                    populateTrackingData(result, camera)
                    processPointDistance(arFrame, arguments, result)
                    result["tracking"] = true
                    result["supported"] = true
                }
                TrackingState.PAUSED -> {
                    result["error"] = "AR tracking paused"
                    result["tracking"] = false
                    result["supported"] = true
                }
                TrackingState.STOPPED -> {
                    result["error"] = "AR tracking stopped"
                    result["tracking"] = false
                    result["supported"] = true
                }
            }
            
            result
        } catch (e: Exception) {
            result["error"] = "Google ARCore error: ${e.message}"
            result["supported"] = false
            result["tracking"] = false
            result
        }
    }
    
    private fun processHuaweiARFrame(frame: Frame, arguments: Map<String, Any>?, result: MutableMap<String, Any?>): Map<String, Any?> {
        // 华为AR Engine处理逻辑
        result["supported"] = true
        result["tracking"] = false
        result["info"] = "Huawei AR Engine detected"
        result["message"] = "Huawei AR functionality requires HMS Core and AR Engine SDK integration"
        
        // 这里可以添加基本的华为AR逻辑
        // 实际使用时需要集成华为AR Engine SDK
        try {
            // 模拟一些基本数据
            result["tx"] = 0.0
            result["ty"] = 0.0
            result["tz"] = 0.0
            result["tracking"] = true
            
            // 处理点测距（模拟）
            processHuaweiPointDistance(arguments, result)
            
        } catch (e: Exception) {
            result["error"] = "Huawei AR processing error: ${e.message}"
        }
        
        return result
    }
    
    private fun processHuaweiPointDistance(arguments: Map<String, Any>?, result: MutableMap<String, Any?>) {
        // 模拟点测距功能
        val point1X = arguments?.get("point1X") as? Number
        val point1Y = arguments?.get("point1Y") as? Number
        val point2X = arguments?.get("point2X") as? Number
        val point2Y = arguments?.get("point2Y") as? Number
        
        if (point1X != null && point1Y != null && point2X != null && point2Y != null) {
            // 模拟距离计算
            val distance = 1.5 + Math.random() * 2.0 // 模拟1.5-3.5米的距离
            result["pointsDistance"] = distance
            result["pointsValid"] = true
            result["message"] = "Huawei AR point distance (simulated)"
        }
    }
    
    private fun populateTrackingData(result: MutableMap<String, Any?>, camera: com.google.ar.core.Camera) {
        val pose = camera.pose
        result["tx"] = pose.tx().toDouble()
        result["ty"] = pose.ty().toDouble()
        result["tz"] = pose.tz().toDouble()
        result["qx"] = pose.qx().toDouble()
        result["qy"] = pose.qy().toDouble()
        result["qz"] = pose.qz().toDouble()
        result["qw"] = pose.qw().toDouble()
        
        result["fov"] = camera.displayOrientedPose.tx().toDouble()
        result["trackingState"] = camera.trackingState.ordinal
    }
    
    private fun processPointDistance(
        arFrame: com.google.ar.core.Frame, 
        arguments: Map<String, Any>?, 
        result: MutableMap<String, Any?>
    ) {
        try {
            val point1X = (arguments?.get("point1X") as? Number)?.toFloat()
            val point1Y = (arguments?.get("point1Y") as? Number)?.toFloat()
            val point2X = (arguments?.get("point2X") as? Number)?.toFloat()
            val point2Y = (arguments?.get("point2Y") as? Number)?.toFloat()
            
            if (point1X != null && point1Y != null && point2X != null && point2Y != null) {
                val hitResults1 = arFrame.hitTest(point1X, point1Y)
                val hitResults2 = arFrame.hitTest(point2X, point2Y)
                
                if (hitResults1.isNotEmpty() && hitResults2.isNotEmpty()) {
                    val hitPose1 = hitResults1[0].hitPose
                    val hitPose2 = hitResults2[0].hitPose
                    
                    val dx = hitPose2.tx() - hitPose1.tx()
                    val dy = hitPose2.ty() - hitPose1.ty()
                    val dz = hitPose2.tz() - hitPose1.tz()
                    val pointsDistance = Math.sqrt((dx * dx + dy * dy + dz * dz).toDouble())
                    
                    result["pointsDistance"] = pointsDistance
                    result["point1X"] = hitPose1.tx().toDouble()
                    result["point1Y"] = hitPose1.ty().toDouble()
                    result["point1Z"] = hitPose1.tz().toDouble()
                    result["point2X"] = hitPose2.tx().toDouble()
                    result["point2Y"] = hitPose2.ty().toDouble()
                    result["point2Z"] = hitPose2.tz().toDouble()
                    result["pointsValid"] = true
                } else {
                    result["pointsValid"] = false
                    result["pointsError"] = "Hit test failed - no surface detected"
                }
            }
        } catch (e: Exception) {
            result["pointsValid"] = false
            result["pointsError"] = "Point processing error: ${e.message}"
        }
    }
    
    fun destroy() {
        if (engineType == AREngineType.GOOGLE_AR_CORE) {
            (session as? Session)?.let {
                if (isSessionRunning.get()) {
                    it.pause()
                    isSessionRunning.set(false)
                }
                it.close()
                Log.d(TAG, "ARCore session destroyed")
            }
        }
    }
    
    private fun isHuaweiDevice(): Boolean {
        return try {
            val manufacturer = android.os.Build.MANUFACTURER.lowercase()
            val brand = android.os.Build.BRAND.lowercase()
            manufacturer.contains("huawei") ||
            brand.contains("huawei")
        } catch (e: Exception) {
            false
        }
    }
}